home *** CD-ROM | disk | FTP | other *** search
/ World of Sound / World of Sound.iso / utils / modplayers / tracker / dec_audio.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-11-11  |  4.0 KB  |  192 lines

  1. /* dec_audio.c
  2.  
  3. This code written by:
  4.  
  5. Andrew "Alf" Leahy                         email: alf@st.nepean.uws.edu.au
  6. University of Western Sydney - Nepean.
  7. Sydney, Australia.                         phone: (047) 360622 (work)
  8. */
  9.  
  10. #include <stdio.h>
  11. #include "defs.h"
  12. #include "extern.h"
  13. #include "/usr/local/include/AF/AFlib.h"
  14.  
  15. /* 0 external handset, 1 for internal speaker */
  16. #define SPEAKER 0
  17.      
  18. LOCAL int stereo, primary, secondary;
  19.  
  20. LOCAL char *buffer, *buffer_r;
  21. LOCAL int nbytes=0, nbytes_r=0, ssize;
  22.  
  23. LOCAL ATime t, t_r, act, act_r;
  24. LOCAL AC ac, ac_r;
  25. LOCAL AFAudioConn *aud, *aud_r;
  26.  
  27. int sample_sizes[] = {
  28.     1,    /* MU255 */
  29.     1,    /* ALAW */
  30.     2,    /* Linear PCM, 16 bits, -1.0 <= x < 1.0 */
  31.     2,    /* Linear PCM, 32 bits, -1.0 <= x < 1.0 */
  32.     1,    /* G.721, 64Kbps to/from 32Kbps. */
  33.     1,    /* G.723, 64Kbps to/from 32Kbps. */
  34.     0
  35. };
  36.  
  37. int open_audio(int f, int s)
  38. {
  39.     AFSetACAttributes attributes;
  40.     int srate, device;
  41.     unsigned int channels;
  42.     AEncodeType type;
  43.     char *server;
  44.  
  45.     device = SPEAKER;
  46.     attributes.preempt = Mix;
  47.     attributes.start_timeout = 0;
  48.     attributes.end_silence = 0;
  49.     attributes.play_gain = 0;
  50.     attributes.rec_gain =  0;
  51.  
  52.     if ((server = (char *) getenv("AUDIOFILE")) == NULL)
  53.     {
  54.         fprintf(stderr, "Error: AUDIOFILE unset\n");
  55.         exit(1);
  56.     }
  57.     else
  58.     {
  59.         server = (char *) getenv("AUDIOFILE");
  60.         if ((aud = AFOpenAudioConn( server )) == NULL) {
  61.             fprintf(stderr, "Error: can't open connection.\n");
  62.             exit(1);
  63.         }
  64.         ac = AFCreateAC(aud, device, ACPlayGain, &attributes);
  65.         srate = ac->device->playSampleFreq;
  66.         type = ac->device->playBufType;
  67.         channels = ac->device->playNchannels;
  68.         ssize = sample_sizes[type] * channels;
  69.  
  70.         if ((buffer = (char *)malloc(ssize * srate)) == NULL) {
  71.             fprintf(stderr, "Couldn't allocate play buffer\n");
  72.             exit(1);
  73.         }
  74.  
  75.         t = AFGetTime(ac);
  76.     }
  77.  
  78.     stereo=s;
  79.  
  80.     if (stereo)
  81.     {
  82.         server = (char *) getenv("AUDIORIGHT");
  83.         if ((aud = AFOpenAudioConn(server)) == NULL) {
  84.             fprintf(stderr, "Error: can't open connection.\n");
  85.             exit(1);
  86.         }
  87.         ac_r = AFCreateAC(aud, device, ACPlayGain, &attributes);
  88.         srate = ac->device->playSampleFreq;
  89.         type = ac->device->playBufType;
  90.         channels = ac->device->playNchannels;
  91.         ssize = sample_sizes[type] * channels;
  92.  
  93.         if ((buffer_r = (char *)malloc(ssize * srate)) == NULL) {
  94.             fprintf(stderr, "Couldn't allocate play buffer\n");
  95.             exit(1);
  96.         }
  97.         t_r = AFGetTime(ac_r);
  98.     }
  99.  
  100.     return srate;
  101. }
  102.  
  103. void set_mix(int percent)
  104. {
  105.     percent *= 256;
  106.     percent /= 100;
  107.     primary = percent;
  108.     secondary = 512 - percent;
  109. }
  110.  
  111. void set_synchro(BOOL s)
  112. {
  113. }
  114.  
  115. int update_frequency()
  116. {
  117.     return 0;
  118. }
  119.  
  120. LOCAL unsigned int cvt(int ch)
  121. {
  122.     int mask;
  123.  
  124.     if (ch < 0)
  125.     {
  126.         ch = -ch;
  127.         mask = 0x7f;
  128.     }
  129.     else
  130.         mask = 0xff;
  131.  
  132.     if (ch < 32)        ch = 0xF0 | 15 - (ch / 2);
  133.     else if (ch < 96)   ch = 0xE0 | 15 - (ch - 32) / 4;
  134.     else if (ch < 224)  ch = 0xD0 | 15 - (ch - 96) / 8;
  135.     else if (ch < 480)  ch = 0xC0 | 15 - (ch - 224) / 16;
  136.     else if (ch < 992)  ch = 0xB0 | 15 - (ch - 480) / 32;
  137.     else if (ch < 2016) ch = 0xA0 | 15 - (ch - 992) / 64;
  138.     else if (ch < 4064) ch = 0x90 | 15 - (ch - 2016) / 128;
  139.     else if (ch < 8160) ch = 0x80 | 15 - (ch - 4064) /  256;
  140.     else ch = 0x80;
  141.  
  142.     return (mask & ch);
  143. }
  144.  
  145. void output_samples(int left, int right)
  146. {
  147.     if (stereo)
  148.         if (primary) /* mixing needed */
  149.         {
  150.             buffer[nbytes++] = cvt((left * primary + right * secondary) >>10);
  151.             buffer_r[nbytes_r++] = cvt((right * primary + left * secondary) >>10);
  152.         }
  153.         else /* no mixing */
  154.         {
  155.             buffer[nbytes++] = cvt(left >>2);
  156.             buffer_r[nbytes_r++] = cvt(right >>2);
  157.         }
  158.     else /* mono */
  159.         buffer[nbytes++] = cvt((left + right) >>2);
  160. }
  161.  
  162. void flush_buffer()
  163. {
  164.     act = AFPlaySamples(ac, t, nbytes, buffer);
  165.     t += nbytes/ssize;
  166.     nbytes = 0;
  167.  
  168.     if (stereo) 
  169.     {
  170.         act_r = AFPlaySamples(ac_r, t_r, nbytes_r, buffer_r);
  171.         t_r += nbytes_r/ssize;
  172.         nbytes_r = 0;
  173.     }
  174. }
  175.  
  176. void discard_buffer()
  177. {
  178. }
  179.  
  180. void close_audio()
  181. {
  182.     free(buffer);
  183.  
  184. /* Alf: I'm not sure whether these functions are needed
  185.         I think these are Seg Faulting... */
  186.  
  187.      (void) AFCloseAudioConn(aud);
  188.  
  189.     if (stereo)
  190.         (void) AFCloseAudioConn(aud_r);
  191. }
  192.